package com.yst.system.service.impl;

import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.yst.common.config.RuoYiConfig;
import com.yst.common.constant.Constants;
import com.yst.common.core.domain.AjaxResult;
import com.yst.common.core.domain.R;
import com.yst.common.core.domain.entity.SysUser;
import com.yst.common.core.domain.model.LoginUser;
import com.yst.common.core.redis.RedisCache;
import com.yst.common.enums.OrderStatus;
import com.yst.common.exception.ServiceException;
import com.yst.common.utils.DateUtils;
import com.yst.common.utils.SecurityUtils;
import com.yst.system.domain.IndexQueryParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.stereotype.Service;

import com.yst.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.yst.system.domain.SellOrderDetail;
import com.yst.system.mapper.SellOrderMapper;
import com.yst.system.domain.SellOrder;
import com.yst.system.service.ISellOrderService;

import javax.servlet.http.HttpServletResponse;

/**
 * 订单信息Service业务层处理
 *
 * @author hoj
 * @date 2024-05-10
 */
@Service
public class SellOrderServiceImpl implements ISellOrderService {
    @Autowired
    private SellOrderMapper sellOrderMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询订单信息
     *
     * @param sellOrderId 订单信息主键
     * @return 订单信息
     */
    @Override
    public SellOrder selectSellOrderBySellOrderId(Long sellOrderId) {
        return sellOrderMapper.selectSellOrderBySellOrderId(sellOrderId);
    }

    /**
     * 查询订单信息列表
     *
     * @param sellOrder 订单信息
     * @return 订单信息
     */
    @Override
    public List<SellOrder> selectSellOrderList(SellOrder sellOrder) {
        return sellOrderMapper.selectSellOrderList(sellOrder);
    }

    /**
     * 新增订单信息
     *
     * @param sellOrder 订单信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertSellOrder(SellOrder sellOrder) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        sellOrder.setCreateTime(DateUtils.getNowDate());
        sellOrder.setCreateBy(user.getUserName());
        sellOrder.setDeptId(user.getDeptId());
        sellOrder.setOrderNo(getOrderSerial(user));
        sellOrder.setOrderDate(DateUtils.getNowDate());
        sellOrder.setStatus(OrderStatus.CREATED.getCode());
        int rows = sellOrderMapper.insertSellOrder(sellOrder);
        insertSellOrderDetail(sellOrder);
        return rows;
    }

    /**
     * 修改订单信息
     *
     * @param sellOrder 订单信息
     * @return 结果
     */
    @Transactional
    @Override
    public int updateSellOrder(SellOrder sellOrder) {
        if (OrderStatus.OK.getCode().equals(sellOrder.getStatus())) {
            sellOrder.setShipmentDate(DateUtils.getNowDate());
        }
        SysUser user = SecurityUtils.getLoginUser().getUser();
        sellOrder.setUpdateBy(user.getUserName());
        sellOrder.setUpdateTime(DateUtils.getNowDate());
        sellOrderMapper.deleteSellOrderDetailBySellOrderId(sellOrder.getSellOrderId());
        insertSellOrderDetail(sellOrder);
        return sellOrderMapper.updateSellOrder(sellOrder);
    }

    /**
     * 批量删除订单信息
     *
     * @param sellOrderIds 需要删除的订单信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteSellOrderBySellOrderIds(Long[] sellOrderIds) {
        sellOrderMapper.deleteSellOrderDetailBySellOrderIds(sellOrderIds);
        return sellOrderMapper.deleteSellOrderBySellOrderIds(sellOrderIds);
    }

    /**
     * 删除订单信息信息
     *
     * @param sellOrderId 订单信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteSellOrderBySellOrderId(Long sellOrderId) {
        sellOrderMapper.deleteSellOrderDetailBySellOrderId(sellOrderId);
        return sellOrderMapper.deleteSellOrderBySellOrderId(sellOrderId);
    }

    @Override
    public void exportOrderInfo(SellOrder sellOrder, HttpServletResponse response) {
        SellOrder param = sellOrderMapper.selectSellOrderBySellOrderId(sellOrder.getSellOrderId());
        Map convert = Convert.convert(Map.class, param);
        //将时间转为字符串类型
        convert.forEach((k, v) -> {
            if (v instanceof Date) {
                convert.put(k, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, (Date) v));
            }
        });
        BigDecimal bigDecimal = new BigDecimal("0");
        List<Map> collect = new ArrayList<>();

        for (int i = 0; i < param.getSellOrderDetailList().size(); i++) {
            SellOrderDetail sellOrderDetail = param.getSellOrderDetailList().get(i);
            Map m = Convert.convert(Map.class, sellOrderDetail);
            if (null != m.get("imgUrl") && !"".equals(m.get("imgUrl"))) {
                try {
                    m.put("imgUrl", new URL(m.get("imgUrl").toString()));
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                }
            }
            m.put("index", i + 1);
            bigDecimal = bigDecimal.add((BigDecimal) m.get("quantity"));
            collect.add(m);
        }

        convert.put("quantity", bigDecimal);
        String templateName = Boolean.valueOf(sellOrder.getParams().get("isDealer").toString())?"/template/orderTemplateBysalesman.xlsx":"/template/orderTemplate.xlsx";
        ExcelWriter excelWriter = null;
        try (InputStream resourceAsStream = this.getClass().getResourceAsStream(templateName)) {
            String filename = URLEncoder.encode("订单(" + param.getOrderNo() + ")", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + filename + ".xlsx");
            //设置response直接下载
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(resourceAsStream).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            // 写入list之前的数据
            excelWriter.fill(convert, writeSheet);
            excelWriter.fill(new FillWrapper("data", collect), fillConfig, writeSheet);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }


    @Override
    public AjaxResult saleByDay(IndexQueryParams indexQueryParams) {
        if (checkParams(indexQueryParams)) {
            return AjaxResult.success();
        }
        List<Map<String, Object>> maps = sellOrderMapper.saleByDay(indexQueryParams);
        Map<Object, List<Map<String, Object>>> collect = maps.stream().collect(Collectors.groupingBy(item -> item.get("deptname")));
        return AjaxResult.success(collect);
    }

    @Override
    public AjaxResult saleByItemType(IndexQueryParams indexQueryParams) {
        if (checkParams(indexQueryParams)) {
            return AjaxResult.success();
        }
        List<Map<String, Object>> list = sellOrderMapper.saleByItemType(indexQueryParams);
        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult saleBySalesman(IndexQueryParams indexQueryParams) {
        if (checkParams(indexQueryParams)) {
            return AjaxResult.success();
        }
        List<Map<String, Object>> list = sellOrderMapper.saleBySalesman(indexQueryParams);
        return AjaxResult.success(list);
    }


    /**
     * @param indexQueryParams
     */
    private boolean checkParams(IndexQueryParams indexQueryParams) {
        return null == indexQueryParams.getStartTime() || null == indexQueryParams.getEndTime();
    }

    /**
     * 新增订单详情信息
     *
     * @param sellOrder 订单信息对象
     */
    public void insertSellOrderDetail(SellOrder sellOrder) {
        List<SellOrderDetail> sellOrderDetailList = sellOrder.getSellOrderDetailList();
        Long sellOrderId = sellOrder.getSellOrderId();
        if (StringUtils.isNotNull(sellOrderDetailList)) {
            List<SellOrderDetail> list = new ArrayList<SellOrderDetail>();
            for (SellOrderDetail sellOrderDetail : sellOrderDetailList) {
                sellOrderDetail.setSellOrderId(sellOrderId);
                list.add(sellOrderDetail);
            }
            if (list.size() > 0) {
                sellOrderMapper.batchSellOrderDetail(list);
            }
        }
    }

    public String getOrderSerial(SysUser user) {
        String check = DateUtils.parseDateToStr(DateUtils.YYYYMMDD, new Date());
        HashOperations hashOperations = redisCache.redisTemplate.opsForHash();
        //查询是否有日期标识 没有则缓存
        if (!hashOperations.hasKey(Constants.ORDER_SERIAL_KEY, check) || 9999 <= (int) hashOperations.get(Constants.ORDER_SERIAL_KEY, check)) {
            hashOperations.put(Constants.ORDER_SERIAL_KEY, check, 0);
        }
        Long increment = hashOperations.increment(Constants.ORDER_SERIAL_KEY, check, 1);
        //补全4位数
        String p = StringUtils.isNotBlank(user.getDept().getDeptCode()) ? user.getDept().getDeptCode() : "T";
        return p + check + NumberUtil.decimalFormat("00000", increment);
    }
}
